<template>
  <Modal v-model="show" fullscreen @on-cancel="handleCancel">

    <div class="picEdit">
      <div class="picEdit-operate">
        <Button @click="handleFileChange">导入图片</Button>
        <Button @click="handleAddRect(null,true)">增加矩形</Button>
        <Button @click="handleAddText(null,true)">增加文字</Button>
        <Button @click="handleAddCircle(null,true)">增加圆形</Button>
      </div>
      <div class="canvas">
        <div id="canvas-layer">
          <Layer v-if="showLayer" ref="layer" @setEditConfig="setEditConfig"></Layer>
        </div>
        <div id="canvas-box">
        </div>
        <div id="canvas-tool">
          <Tool v-if="showTool" ref="tool"></Tool>

        </div>
      </div>
    </div>
    <div slot="footer" class="flex-start-end">
      <Button @click="handleCancel">取消</Button>
      <Button @click="handleConfirm">生成图片</Button>
    </div>
  </Modal>

</template>
<script>
import {fabric} from 'fabric'
import {base64ToImageData, blobToBase64, debounce, fileImport} from '@/util/file'
import {initControl, resetBgToFront,} from './util'

import Layer from "@/components/PicEdit/Layer.vue";
import Tool from "@/components/PicEdit/Tool.vue";
import {v4 as uuid} from 'uuid'
import {getInstance, instance} from "@/util/canvasEditor";

if (module.hot) {
  module.hot.accept("@/components/PicEdit/index.vue")
  module.hot.accept("@/components/PicEdit/Layer.vue")
  module.hot.accept("@/components/PicEdit/Tool.vue")
}
const defaultColor = '#FD091F'
export default {
  components: {
    Layer,
    Tool
  },
  provide() {
    return {
      canvas: () => this.canvas
    }
  },
  data() {
    return {
      canvas: null,
      timer: null,
      ratio: 1,
      currentConfig: null,
      modalCache: {
        index: 0,
        base64: '',
        config: null
      },
      activeObject: null,
      showTool: false,
      showLayer: false,
      instance: null,
      show: false,
      dounceFn: debounce((e) => {

        console.log(e)
      }, 2000)
    }
  },
  methods: {
    handleCancel() {
      this.show = false;
      this.$nextTick(() => {
        this.$emit('handleCancel', false)
      })

    },
    handleConfirm() {
      console.log(this.modalCache)
      this.modalCache.base64 = this.canvas.toDataURL({
        format: 'png',
        quality: 1
      });
      this.modalCache.config = this.canvas.toJSON()
      this.$emit('handleConfirm', this.modalCache)
      this.handleCancel()
    },
    async open(parentData) {
      this.modalCache = parentData;
      this.show = true;

      if (parentData.config) {
        const {objects} = parentData.config;
        const restObjects = objects.slice(1)
        await this.addImageBackground(objects[0].src)
        restObjects.forEach(itemConfig => {

          if (itemConfig.type === 'rect') {
            this.handleAddRect(itemConfig)
          }
          if (itemConfig.type === 'circle') {
            this.handleAddCircle(itemConfig)
          }
          if (itemConfig.type === 'i-text') {
            this.handleAddText(itemConfig, false)
          }
        })
        this.canvas.renderAll()
        this.showLayer = true;
        this.$nextTick(() => {
          this.$refs.layer.getLayerList()
        })

      }

    },
    listen(e) {
      this.dounceFn(e)
    },
    setEditConfig() {
      this.showTool = false
      const activeObject = this.canvas.getActiveObject()
      if (activeObject) {
        this.showTool = true
        this.$nextTick(() => {
          this.$refs.tool.setEditConfig(activeObject)
        })

      }

    },
    initMouseUp() {
      this.canvas.on('mouse:up', () => {
        this.setEditConfig()
      })

    },
    destroyCanvas() {
      this.showLayer = false;
      this.showTool = false;
      if (this.canvas) {
        const canvasBox = document.getElementById('canvas-box')
        const canvasContainer = document.querySelector('#canvas-box .canvas-container')
        canvasBox.removeChild(canvasContainer)
        canvasBox.style = null
        this.canvas.dispose();
        this.canvas = null
      }
    },
    async initCanvas(base64) {
      this.destroyCanvas()
      const imageData = await base64ToImageData(base64);
      this.instance = getInstance('canvas-box', imageData);
      this.canvas = this.instance.canvas
      this.ratio = this.instance.ratio
      this.canvas.on('object:scaling', this.listen)
    },
    // 添加背景图片
    async addImageBackground(base64) {
      await this.initCanvas(base64)
      this.initMouseUp()
      fabric.Image.fromURL(base64,
          (imgCanvas) => {
            imgCanvas.centeredScaling = true;//配合以上操作
            imgCanvas.centerTransform = true;
            imgCanvas.lockMovementX = true;
            imgCanvas.lockMovementY = true;
            imgCanvas.setControlsVisibility({
              bl: false,
              br: false,
              mt: false,
              mr: false,
              mb: false,
              ml: false,
              tl: false,
              tr: false,
              mtr: false
            })
            imgCanvas.id = 'backgroundImage'
            imgCanvas.selectable = false;
            imgCanvas.hoverCursor = 'default'

            this.canvas.add(imgCanvas);
            this.canvas.centerObject(imgCanvas);
            imgCanvas.sendToBack()
          }
      );

    },
    async handleFileChange() {
      fileImport(async (event) => {
        const files = event.target.files
        const base64 = await blobToBase64(files[0])
        await this.addImageBackground(base64)
        // 展示图层
        this.showLayer = true;
      }, {filesType: '.jpg,jpeg,.png'})

    },
    handleAddCircle(config = null) {
      const circle = new fabric.Circle(config ? config : {
        radius: 15 / this.ratio,
        fill: defaultColor,
        left: 100 / this.ratio,
        top: 100 / this.ratio,
        scaleY: 1,
        scaleX: 1,
        zoomY: 1,
        zoomX: 1
      })
      circle.setControlsVisibility({
        bl: false,
        br: false,
        mt: false,
        mr: false,
        mb: false,
        ml: false,
        tl: false,
        tr: false,
        mtr: false
      })
      circle.set({id: uuid()})
      this.canvas.add(circle);
    },
    handleAddText(config = null, edit = true) {
      const text = new fabric.IText('点击编辑文字', config ? config : {
        fill: '#000000',
        fontSize: 20 / this.ratio,
        fontFamily: 'SourceHanSansCN-Normal'
      })
      text.setControlsVisibility({
        bl: false,
        br: false,
        mt: false,
        mr: false,
        mb: false,
        ml: false,
        tl: false,
        tr: false,
        mtr: false
      })
      text.set({id: uuid()})
      this.canvas.add(text);

      if (edit) {
        text.enterEditing();
        text.selectAll()
        this.canvas.setActiveObject(text);
      }

    },
    // handleExport() {
    //   var dataURL = this.canvas.toDataURL({
    //     format: 'jpeg',
    //     quality: 1
    //   });
    //   console.log(dataURL)
    // },
    handleAddRect(config) {
      const left = 100

      const rect = new fabric.Rect(config ? config : {
        left: left / this.ratio,
        top: 50 / this.ratio,
        fill: 'transparent',
        width: 200 / this.ratio,
        height: 100 / this.ratio,
        stroke: defaultColor,
        strokeWidth: 5 / this.ratio,
        strokeUniform: true,
        scaleY: 1,
        scaleX: 1
      });
      rect.set({id: uuid()})
      this.canvas.add(rect);
      this.canvas.setActiveObject(rect);

    },

    moveToPrevFloor() {
      const actives = this.canvas.getActiveObjects();

      if (actives && actives.length === 1) {
        const activeObject = this.canvas.getActiveObjects()[0];
        activeObject && activeObject.bringForward();
        resetBgToFront(this.canvas)
        this.canvas.renderAll();
      }
    },
    moveToNextFloor() {

      const actives = this.canvas.getActiveObjects();
      if (actives && actives.length === 1) {
        const activeObject = this.canvas.getActiveObjects()[0];
        activeObject && activeObject.sendBackwards();
        resetBgToFront(this.canvas)
        this.canvas.renderAll();
      }
    }
  }
}
</script>


<style lang="scss" scoped>
.picEdit {
  height: 100%;

  .canvas {
    background: url();
    display: flex;
    justify-content: center;
    height: calc(100% - 27px);
    position: relative;

    #canvas-layer {
      width: 20%;
      height: 100%;
      background-color: #ffffff;
      position: absolute;
      left: 0;
      top: 0;
      padding: 16px;
      overflow-y: auto;
    }

    #canvas-tool {
      width: 20%;
      height: 100%;
      background-color: #ffffff;
      position: absolute;
      right: 0;
      top: 0;
      padding: 16px;
      overflow-y: auto;


    }
  }
}
</style>
